import g3a_heatmap from '../HeatMap';
import { JulianDate } from '@cesiumjs';

const defaultOptions = g3a_heatmap.defaultOptions

class HeatMapSerious {
  constructor(viewer, options, dataSources) {
    this.viewer = viewer;
    this.options = {
      ...defaultOptions,
      ...options
    }
    this.init();
    this.heatmap = new g3a_heatmap(viewer, options);
    this.setDataSource(dataSources);
  }

  init() {
    const _this = this;
    var { rows,columns, timeStart, timeEnd } = this.options;

    this.options._timeStart = JulianDate.fromIso8601(timeStart, new JulianDate())
    this.options._timeEnd = JulianDate.fromIso8601(timeEnd, new JulianDate())
    this.options._timeDuration = JulianDate.secondsDifference(this.options._timeEnd, this.options._timeStart)

    this.options._gridBuff = new Array(rows * columns);
    this.options._gridBuff.fill(0);

    const clock = this.viewer.clock;

    _this._eventListener =
      _this.viewer.scene.preUpdate.addEventListener(() => {
        const gridData = _this.interpolateGrid(clock.currentTime)
        _this.heatmap.setGridData(gridData);
      });
  }

  setDataSource(dataSources) {
    // if(!dataSources) return;

    dataSources = dataSources||[];

    this.dataSources = dataSources;

    var { rows, columns, _timeStart, _timeDuration } = this.options;

    const gridData0 = new Array(rows * columns);
    gridData0.fill(0);

    let secondsDiff = 0;
    const dataSet = [{grid:gridData0,secondsDiff}];

    dataSources.forEach((e)=>{
      if(e.time){
        const grid = new Array(rows * columns);
        grid.fill(0);
        g3a_heatmap.getGridDataFromKriging(e.data, rows, columns, grid);

        const time = JulianDate.fromIso8601(e.time, new JulianDate())
        secondsDiff = JulianDate.secondsDifference(time, _timeStart)
        dataSet.push({grid,secondsDiff})
      }
    })

    const gridData1 = new Array(rows * columns);
    gridData1.fill(0);

    secondsDiff = _timeDuration
    dataSet.push({grid:gridData1,secondsDiff})

    this.dataSet = dataSet;
  }

  selectData(date){
    var { rows, columns, _timeStart, _timeDuration } = this.options;

    const secondsDiff = JulianDate.secondsDifference(date, _timeStart)
    if(secondsDiff<0) return [this.dataSet[0],this.dataSet[0]];
    const n=this.dataSet.length
    for(let i=0; i<n; ++i){
      const data1 = this.dataSet[i];
      if(i+1==n){
        return [data1,data1]
      }
      if(secondsDiff==data1.secondsDiff){
        return [data1,data1];
      }
      const data2 = this.dataSet[i+1];
      if(secondsDiff<data2.secondsDiff){
        const r = (secondsDiff-data1.secondsDiff)/(data2.secondsDiff-data1.secondsDiff)
        return [data1,data2, r];
      }
    }
    return [this.dataSet[n-1],this.dataSet[n-1]];
  }

  interpolateGrid(date) {
    var { rows, columns, _gridBuff } = this.options;
    const [data1,data2,ratio] = this.selectData(date);
    if(!ratio){
      return data1.grid;
    }
    return g3a_heatmap.interpolateGridData2(ratio, data1.grid, data2.grid, rows * columns, _gridBuff);
  }

  play(){
    this.playing = true
  }

  stop(){
    this.playing = false
  }

  flyTo(options) {
    this.heatmap && this.heatmap.flyTo(options)
  }

  destroy() {
    const {
      _eventListener,
      viewer
    } = this;
    _eventListener && viewer.scene.preUpdate.addEventListener(_eventListener);
    this._eventListener = null;
  }

}

export default HeatMapSerious;
